// The following is an external n-ary tree implementation. It is fairly bulky
// and has many features that we have no use for so we should probably make our
// own trimmed-down tree implementation at some point.

//  STL-like templated tree class.
//
// Copyright (C) 2001-2011 Kasper Peeters <kasper@phi-sci.com>
// Distributed under the GNU General Public License version 3.
//
// When used together with the htmlcxx library to create 
// HTML::Node template instances, the GNU Lesser General Public 
// version 2 applies. Special permission to use tree.hh under
// the LGPL for other projects can be requested from the author.

/** \mainpage tree.hh
    \author   Kasper Peeters
    \version  2.81
    \date     23-Aug-2011
    \see      http://tree.phi-sci.com/
    \see      http://tree.phi-sci.com/ChangeLog

   The tree.hh library for C++ provides an STL-like container class
   for n-ary trees, templated over the data stored at the
   nodes. Various types of iterators are provided (post-order,
   pre-order, and others). Where possible the access methods are
   compatible with the STL or alternative algorithms are
   available. 
*/

#ifndef GMML_INTERNAL_TREE_H_
#define GMML_INTERNAL_TREE_H_

#include <cassert>
#include <memory>
#include <stdexcept>
#include <iterator>
#include <set>
#include <queue>
#include <algorithm>
#include <cstddef>

namespace gmml {
namespace internal {

/// A node in the tree, combining links to other nodes as well as the actual data.
template<class T>
class tree_node_ { // size: 5*4=20 bytes (on 32 bit arch), can be reduced by 8.
  public:
    tree_node_();
    tree_node_(const T&);

    tree_node_<T> *parent;
     tree_node_<T> *first_child, *last_child;
    tree_node_<T> *prev_sibling, *next_sibling;
    T data;
}; // __attribute__((packed));

template<class T>
tree_node_<T>::tree_node_()
  : parent(0), first_child(0), last_child(0), prev_sibling(0), next_sibling(0)
  {
  }

template<class T>
tree_node_<T>::tree_node_(const T& val)
  : parent(0), first_child(0), last_child(0), prev_sibling(0), next_sibling(0), data(val)
  {
  }

template <class T, class tree_node_allocator = std::allocator<tree_node_<T> > >
class tree {
  protected:
    typedef tree_node_<T> tree_node;
  public:
    /// Value of the data stored at a node.
    typedef T value_type;

    class iterator_base;
    class pre_order_iterator;
    class post_order_iterator;
    class sibling_iterator;
      class leaf_iterator;

    tree();
    tree(const T&);
    tree(const iterator_base&);
    tree(const tree<T, tree_node_allocator>&);
    ~tree();
    tree<T,tree_node_allocator>& operator=(const tree<T, tree_node_allocator>&);

      /// Base class for iterators, only pointers stored, no traversal logic.
#ifdef __SGI_STL_PORT
    class iterator_base : public stlport::bidirectional_iterator<T, ptrdiff_t> {
#else
    class iterator_base {
#endif
      public:
        typedef T                               value_type;
        typedef T*                              pointer;
        typedef T&                              reference;
        typedef size_t                          size_type;
        typedef ptrdiff_t                       difference_type;
        typedef std::bidirectional_iterator_tag iterator_category;

        iterator_base();
        iterator_base(tree_node *);

        T&             operator*() const;
        T*             operator->() const;

            /// When called, the next increment/decrement skips children of this node.
        void         skip_children();
        void         skip_children(bool skip);
        /// Number of children of the node pointed to by the iterator.
        unsigned int number_of_children() const;

        sibling_iterator begin() const;
        sibling_iterator end() const;

        tree_node *node;
      protected:
        bool skip_current_children_;
    };

    /// Depth-first iterator, first accessing the node, then its children.
    class pre_order_iterator : public iterator_base { 
      public:
        pre_order_iterator();
        pre_order_iterator(tree_node *);
        pre_order_iterator(const iterator_base&);
        pre_order_iterator(const sibling_iterator&);

        bool    operator==(const pre_order_iterator&) const;
        bool    operator!=(const pre_order_iterator&) const;
        pre_order_iterator&  operator++();
         pre_order_iterator&  operator--();
        pre_order_iterator   operator++(int);
        pre_order_iterator   operator--(int);
        pre_order_iterator&  operator+=(unsigned int);
        pre_order_iterator&  operator-=(unsigned int);
    };

    /// Depth-first iterator, first accessing the children, then the node itself.
    class post_order_iterator : public iterator_base {
      public:
        post_order_iterator();
        post_order_iterator(tree_node *);
        post_order_iterator(const iterator_base&);
        post_order_iterator(const sibling_iterator&);

        bool    operator==(const post_order_iterator&) const;
        bool    operator!=(const post_order_iterator&) const;
        post_order_iterator&  operator++();
         post_order_iterator&  operator--();
        post_order_iterator   operator++(int);
        post_order_iterator   operator--(int);
        post_order_iterator&  operator+=(unsigned int);
        post_order_iterator&  operator-=(unsigned int);

        /// Set iterator to the first child as deep as possible down the tree.
        void descend_all();
    };

    /// Breadth-first iterator, using a queue
    class breadth_first_queued_iterator : public iterator_base {
      public:
        breadth_first_queued_iterator();
        breadth_first_queued_iterator(tree_node *);
        breadth_first_queued_iterator(const iterator_base&);

        bool    operator==(const breadth_first_queued_iterator&) const;
        bool    operator!=(const breadth_first_queued_iterator&) const;
        breadth_first_queued_iterator&  operator++();
        breadth_first_queued_iterator   operator++(int);
        breadth_first_queued_iterator&  operator+=(unsigned int);

      private:
        std::queue<tree_node *> traversal_queue;
    };

    /// The default iterator types throughout the tree class.
    typedef pre_order_iterator            iterator;
    typedef breadth_first_queued_iterator breadth_first_iterator;

    /// Iterator which traverses only the nodes at a given depth from the root.
    class fixed_depth_iterator : public iterator_base {
      public:
        fixed_depth_iterator();
        fixed_depth_iterator(tree_node *);
        fixed_depth_iterator(const iterator_base&);
        fixed_depth_iterator(const sibling_iterator&);
        fixed_depth_iterator(const fixed_depth_iterator&);

        bool    operator==(const fixed_depth_iterator&) const;
        bool    operator!=(const fixed_depth_iterator&) const;
        fixed_depth_iterator&  operator++();
         fixed_depth_iterator&  operator--();
        fixed_depth_iterator   operator++(int);
        fixed_depth_iterator   operator--(int);
        fixed_depth_iterator&  operator+=(unsigned int);
        fixed_depth_iterator&  operator-=(unsigned int);

        tree_node *top_node;
    };

    /// Iterator which traverses only the nodes which are siblings of each other.
    class sibling_iterator : public iterator_base {
      public:
        sibling_iterator();
        sibling_iterator(tree_node *);
        sibling_iterator(const sibling_iterator&);
        sibling_iterator(const iterator_base&);

        bool    operator==(const sibling_iterator&) const;
        bool    operator!=(const sibling_iterator&) const;
        sibling_iterator&  operator++();
        sibling_iterator&  operator--();
        sibling_iterator   operator++(int);
        sibling_iterator   operator--(int);
        sibling_iterator&  operator+=(unsigned int);
        sibling_iterator&  operator-=(unsigned int);

        tree_node *range_first() const;
        tree_node *range_last() const;
        tree_node *parent_;
      private:
        void set_parent_();
    };

      /// Iterator which traverses only the leaves.
      class leaf_iterator : public iterator_base {
         public:
            leaf_iterator();
            leaf_iterator(tree_node *, tree_node *top=0);
            leaf_iterator(const sibling_iterator&);
            leaf_iterator(const iterator_base&);

            bool    operator==(const leaf_iterator&) const;
            bool    operator!=(const leaf_iterator&) const;
            leaf_iterator&  operator++();
            leaf_iterator&  operator--();
            leaf_iterator   operator++(int);
            leaf_iterator   operator--(int);
            leaf_iterator&  operator+=(unsigned int);
            leaf_iterator&  operator-=(unsigned int);
      private:
        tree_node *top_node;
      };

    /// Return iterator to the beginning of the tree.
    inline pre_order_iterator   begin() const;
    /// Return iterator to the end of the tree.
    inline pre_order_iterator   end() const;
    /// Return post-order iterator to the beginning of the tree.
    post_order_iterator  begin_post() const;
    /// Return post-order end iterator of the tree.
    post_order_iterator  end_post() const;
    /// Return fixed-depth iterator to the first node at a given depth from the given iterator.
    fixed_depth_iterator begin_fixed(const iterator_base&, unsigned int) const;
    /// Return fixed-depth end iterator.
    fixed_depth_iterator end_fixed(const iterator_base&, unsigned int) const;
    /// Return breadth-first iterator to the first node at a given depth.
    breadth_first_queued_iterator begin_breadth_first() const;
    /// Return breadth-first end iterator.
    breadth_first_queued_iterator end_breadth_first() const;
    /// Return sibling iterator to the first child of given node.
    sibling_iterator     begin(const iterator_base&) const;
    /// Return sibling end iterator for children of given node.
    sibling_iterator     end(const iterator_base&) const;
      /// Return leaf iterator to the first leaf of the tree.
      leaf_iterator   begin_leaf() const;
      /// Return leaf end iterator for entire tree.
      leaf_iterator   end_leaf() const;
      /// Return leaf iterator to the first leaf of the subtree at the given node.
      leaf_iterator   begin_leaf(const iterator_base& top) const;
      /// Return leaf end iterator for the subtree at the given node.
      leaf_iterator   end_leaf(const iterator_base& top) const;

    /// Return iterator to the parent of a node.
    template<typename  iter> static iter parent(iter);
    /// Return iterator to the previous sibling of a node.
    template<typename iter> iter previous_sibling(iter) const;
    /// Return iterator to the next sibling of a node.
    template<typename iter> iter next_sibling(iter) const;
    /// Return iterator to the next node at a given depth.
    template<typename iter> iter next_at_same_depth(iter) const;

    /// Erase all nodes of the tree.
    void     clear();
    /// Erase element at position pointed to by iterator, return incremented iterator.
    template<typename iter> iter erase(iter);
    /// Erase all children of the node pointed to by iterator.
    void     erase_children(const iterator_base&);

    /// Insert empty node as last/first child of node pointed to by position.
    template<typename iter> iter append_child(iter position); 
    template<typename iter> iter prepend_child(iter position); 
    /// Insert node as last/first child of node pointed to by position.
    template<typename iter> iter append_child(iter position, const T& x);
    template<typename iter> iter prepend_child(iter position, const T& x);
    /// Append the node (plus its children) at other_position as last/first child of position.
    template<typename iter> iter append_child(iter position, iter other_position);
    template<typename iter> iter prepend_child(iter position, iter other_position);
    /// Append the nodes in the from-to range (plus their children) as last/first children of position.
    template<typename iter> iter append_children(iter position, sibling_iterator from, sibling_iterator to);
    template<typename iter> iter prepend_children(iter position, sibling_iterator from, sibling_iterator to);

    /// Short-hand to insert topmost node in otherwise empty tree.
    pre_order_iterator set_head(const T& x);
    /// Insert node as previous sibling of node pointed to by position.
    template<typename iter> iter insert(iter position, const T& x);
    /// Specialisation of previous member.
    sibling_iterator insert(sibling_iterator position, const T& x);
    /// Insert node (with children) pointed to by subtree as previous sibling of node pointed to by position.
    template<typename iter> iter insert_subtree(iter position, const iterator_base& subtree);
    /// Insert node as next sibling of node pointed to by position.
    template<typename iter> iter insert_after(iter position, const T& x);
    /// Insert node (with children) pointed to by subtree as next sibling of node pointed to by position.
    template<typename iter> iter insert_subtree_after(iter position, const iterator_base& subtree);

    /// Replace node at 'position' with other node (keeping same children); 'position' becomes invalid.
    template<typename iter> iter replace(iter position, const T& x);
    /// Replace node at 'position' with subtree starting at 'from' (do not erase subtree at 'from'); see above.
    template<typename iter> iter replace(iter position, const iterator_base& from);
    /// Replace string of siblings (plus their children) with copy of a new string (with children); see above
    sibling_iterator replace(sibling_iterator orig_begin, sibling_iterator orig_end, 
                     sibling_iterator new_begin,  sibling_iterator new_end); 

    /// Move all children of node at 'position' to be siblings, returns position.
    template<typename iter> iter flatten(iter position);
    /// Move nodes in range to be children of 'position'.
    template<typename iter> iter reparent(iter position, sibling_iterator begin, sibling_iterator end);
    /// Move all child nodes of 'from' to be children of 'position'.
    template<typename iter> iter reparent(iter position, iter from);

    /// Replace node with a new node, making the old node a child of the new node.
    template<typename iter> iter wrap(iter position, const T& x);

    /// Move 'source' node (plus its children) to become the next sibling of 'target'.
    template<typename iter> iter move_after(iter target, iter source);
    /// Move 'source' node (plus its children) to become the previous sibling of 'target'.
      template<typename iter> iter move_before(iter target, iter source);
      sibling_iterator move_before(sibling_iterator target, sibling_iterator source);
    /// Move 'source' node (plus its children) to become the node at 'target' (erasing the node at 'target').
    template<typename iter> iter move_ontop(iter target, iter source);

    /// Merge with other tree, creating new branches and leaves only if they are not already present.
    void     merge(sibling_iterator, sibling_iterator, sibling_iterator, sibling_iterator, 
              bool duplicate_leaves=false);
    /// Sort (std::sort only moves values of nodes, this one moves children as well).
    void     sort(sibling_iterator from, sibling_iterator to, bool deep=false);
    template<class StrictWeakOrdering>
    void     sort(sibling_iterator from, sibling_iterator to, StrictWeakOrdering comp, bool deep=false);
    /// Compare two ranges of nodes (compares nodes as well as tree structure).
    template<typename iter>
    bool     equal(const iter& one, const iter& two, const iter& three) const;
    template<typename iter, class BinaryPredicate>
    bool     equal(const iter& one, const iter& two, const iter& three, BinaryPredicate) const;
    template<typename iter>
    bool     equal_subtree(const iter& one, const iter& two) const;
    template<typename iter, class BinaryPredicate>
    bool     equal_subtree(const iter& one, const iter& two, BinaryPredicate) const;
    /// Extract a new tree formed by the range of siblings plus all their children.
    tree     subtree(sibling_iterator from, sibling_iterator to) const;
    void     subtree(tree&, sibling_iterator from, sibling_iterator to) const;
    /// Exchange the node (plus subtree) with its sibling node (do nothing if no sibling present).
    void     swap(sibling_iterator it);
    /// Exchange two nodes (plus subtrees)
     void     swap(iterator, iterator);
    
    /// Count the total number of nodes.
    size_t   size() const;
    /// Count the total number of nodes below the indicated node (plus one).
    size_t   size(const iterator_base&) const;
    /// Check if tree is empty.
    bool     empty() const;
    /// Compute the depth to the root or to a fixed other iterator.
    static int depth(const iterator_base&);
    static int depth(const iterator_base&, const iterator_base&);
    /// Determine the maximal depth of the tree. An empty tree has max_depth=-1.
    int      max_depth() const;
    /// Determine the maximal depth of the tree with top node at the given position.
    int      max_depth(const iterator_base&) const;
    /// Count the number of children of node at position.
    static unsigned int number_of_children(const iterator_base&);
    /// Count the number of siblings (left and right) of node at iterator. Total nodes at this level is +1.
    unsigned int number_of_siblings(const iterator_base&) const;
    /// Determine whether node at position is in the subtrees with root in the range.
    bool     is_in_subtree(const iterator_base& position, const iterator_base& begin, 
                    const iterator_base& end) const;
    /// Determine whether the iterator is an 'end' iterator and thus not actually pointing to a node.
    bool     is_valid(const iterator_base&) const;
    /// Find the lowest common ancestor of two nodes, that is, the deepest node such that
    /// both nodes are descendants of it.
    iterator lowest_common_ancestor(const iterator_base&, const iterator_base &) const;

    /// Determine the index of a node in the range of siblings to which it belongs.
    unsigned int index(sibling_iterator it) const;
    /// Inverse of 'index': return the n-th child of the node at position.
    static sibling_iterator child(const iterator_base& position, unsigned int);
    /// Return iterator to the sibling indicated by index
    sibling_iterator sibling(const iterator_base& position, unsigned int);          
    
    /// For debugging only: verify internal consistency by inspecting all pointers in the tree
    /// (which will also trigger a valgrind error in case something got corrupted).
    void debug_verify_consistency() const;
    
    /// Comparator class for iterators (compares pointer values; why doesn't this work automatically?)
    class iterator_base_less {
      public:
        bool operator()(const typename tree<T, tree_node_allocator>::iterator_base& one,
                   const typename tree<T, tree_node_allocator>::iterator_base& two) const
          {
          return one.node < two.node;
          }
    };
    tree_node *head, *feet;    // head/feet are always dummy; if an iterator points to them it is invalid
  private:
    tree_node_allocator alloc_;
    void head_initialise_();
    void copy_(const tree<T, tree_node_allocator>& other);

      /// Comparator class for two nodes of a tree (used for sorting and searching).
    template<class StrictWeakOrdering>
    class compare_nodes {
      public:
        compare_nodes(StrictWeakOrdering comp) : comp_(comp) {};
        
        bool operator()(const tree_node *a, const tree_node *b) 
          {
          return comp_(a->data, b->data);
          }
      private:
        StrictWeakOrdering comp_;
    };
};

//template <class T, class tree_node_allocator>
//class iterator_base_less {
//  public:
//    bool operator()(const typename tree<T, tree_node_allocator>::iterator_base& one,
//              const typename tree<T, tree_node_allocator>::iterator_base& two) const
//      {
//      txtout << "operatorclass<" << one.node < two.node << std::endl;
//      return one.node < two.node;
//      }
//};

// template <class T, class tree_node_allocator>
// bool operator<(const typename tree<T, tree_node_allocator>::iterator& one,
//           const typename tree<T, tree_node_allocator>::iterator& two)
//   {
//   txtout << "operator< " << one.node < two.node << std::endl;
//   if(one.node < two.node) return true;
//   return false;
//   }
// 
// template <class T, class tree_node_allocator>
// bool operator==(const typename tree<T, tree_node_allocator>::iterator& one,
//           const typename tree<T, tree_node_allocator>::iterator& two)
//   {
//   txtout << "operator== " << one.node == two.node << std::endl;
//   if(one.node == two.node) return true;
//   return false;
//   }
// 
// template <class T, class tree_node_allocator>
// bool operator>(const typename tree<T, tree_node_allocator>::iterator_base& one,
//           const typename tree<T, tree_node_allocator>::iterator_base& two)
//   {
//   txtout << "operator> " << one.node < two.node << std::endl;
//   if(one.node > two.node) return true;
//   return false;
//   }



// Tree

template <class T, class tree_node_allocator>
tree<T, tree_node_allocator>::tree() 
  {
  head_initialise_();
  }

template <class T, class tree_node_allocator>
tree<T, tree_node_allocator>::tree(const T& x) 
  {
  head_initialise_();
  set_head(x);
  }

template <class T, class tree_node_allocator>
tree<T, tree_node_allocator>::tree(const iterator_base& other)
  {
  head_initialise_();
  set_head((*other));
  replace(begin(), other);
  }

template <class T, class tree_node_allocator>
tree<T, tree_node_allocator>::~tree()
  {
  clear();
  alloc_.destroy(head);
  alloc_.destroy(feet);
  alloc_.deallocate(head,1);
  alloc_.deallocate(feet,1);
  }

template <class T, class tree_node_allocator>
void tree<T, tree_node_allocator>::head_initialise_() 
   { 
   head = alloc_.allocate(1,0); // MSVC does not have default second argument 
  feet = alloc_.allocate(1,0);
  alloc_.construct(head, tree_node_<T>());
  alloc_.construct(feet, tree_node_<T>());

   head->parent=0;
   head->first_child=0;
   head->last_child=0;
   head->prev_sibling=0; //head;
   head->next_sibling=feet; //head;

  feet->parent=0;
  feet->first_child=0;
  feet->last_child=0;
  feet->prev_sibling=head;
  feet->next_sibling=0;
   }

template <class T, class tree_node_allocator>
tree<T,tree_node_allocator>& tree<T, tree_node_allocator>::operator=(const tree<T, tree_node_allocator>& other)
  {
  if(this != &other)
    copy_(other);
  return *this;
  }

template <class T, class tree_node_allocator>
tree<T, tree_node_allocator>::tree(const tree<T, tree_node_allocator>& other)
  {
  head_initialise_();
  copy_(other);
  }

template <class T, class tree_node_allocator>
void tree<T, tree_node_allocator>::copy_(const tree<T, tree_node_allocator>& other) 
  {
  clear();
  pre_order_iterator it=other.begin(), to=begin();
  while(it!=other.end()) {
    to=insert(to, (*it));
    it.skip_children();
    ++it;
    }
  to=begin();
  it=other.begin();
  while(it!=other.end()) {
    to=replace(to, it);
    to.skip_children();
    it.skip_children();
    ++to;
    ++it;
    }
  }

template <class T, class tree_node_allocator>
void tree<T, tree_node_allocator>::clear()
  {
  if(head)
    while(head->next_sibling!=feet)
      erase(pre_order_iterator(head->next_sibling));
  }

template<class T, class tree_node_allocator> 
void tree<T, tree_node_allocator>::erase_children(const iterator_base& it)
  {
//  std::cout << "erase_children " << it.node << std::endl;
  if(it.node==0) return;

  tree_node *cur=it.node->first_child;
  tree_node *prev=0;

  while(cur!=0) {
    prev=cur;
    cur=cur->next_sibling;
    erase_children(pre_order_iterator(prev));
//    kp::destructor(&prev->data);
    alloc_.destroy(prev);
    alloc_.deallocate(prev,1);
    }
  it.node->first_child=0;
  it.node->last_child=0;
//  std::cout << "exit" << std::endl;
  }

template<class T, class tree_node_allocator> 
template<class iter>
iter tree<T, tree_node_allocator>::erase(iter it)
  {
  tree_node *cur=it.node;
  assert(cur!=head);
  iter ret=it;
  ret.skip_children();
  ++ret;
  erase_children(it);
  if(cur->prev_sibling==0) {
    cur->parent->first_child=cur->next_sibling;
    }
  else {
    cur->prev_sibling->next_sibling=cur->next_sibling;
    }
  if(cur->next_sibling==0) {
    cur->parent->last_child=cur->prev_sibling;
    }
  else {
    cur->next_sibling->prev_sibling=cur->prev_sibling;
    }

//  kp::destructor(&cur->data);
  alloc_.destroy(cur);
   alloc_.deallocate(cur,1);
  return ret;
  }

template <class T, class tree_node_allocator>
typename tree<T, tree_node_allocator>::pre_order_iterator tree<T, tree_node_allocator>::begin() const
  {
  return pre_order_iterator(head->next_sibling);
  }

template <class T, class tree_node_allocator>
typename tree<T, tree_node_allocator>::pre_order_iterator tree<T, tree_node_allocator>::end() const
  {
  return pre_order_iterator(feet);
  }

template <class T, class tree_node_allocator>
typename tree<T, tree_node_allocator>::breadth_first_queued_iterator tree<T, tree_node_allocator>::begin_breadth_first() const
  {
  return breadth_first_queued_iterator(head->next_sibling);
  }

template <class T, class tree_node_allocator>
typename tree<T, tree_node_allocator>::breadth_first_queued_iterator tree<T, tree_node_allocator>::end_breadth_first() const
  {
  return breadth_first_queued_iterator();
  }

template <class T, class tree_node_allocator>
typename tree<T, tree_node_allocator>::post_order_iterator tree<T, tree_node_allocator>::begin_post() const
  {
  tree_node *tmp=head->next_sibling;
  if(tmp!=feet) {
    while(tmp->first_child)
      tmp=tmp->first_child;
    }
  return post_order_iterator(tmp);
  }

template <class T, class tree_node_allocator>
typename tree<T, tree_node_allocator>::post_order_iterator tree<T, tree_node_allocator>::end_post() const
  {
  return post_order_iterator(feet);
  }

template <class T, class tree_node_allocator>
typename tree<T, tree_node_allocator>::fixed_depth_iterator tree<T, tree_node_allocator>::begin_fixed(const iterator_base& pos, unsigned int dp) const
  {
  typename tree<T, tree_node_allocator>::fixed_depth_iterator ret;
  ret.top_node=pos.node;

  tree_node *tmp=pos.node;
  unsigned int curdepth=0;
  while(curdepth<dp) { // go down one level
    while(tmp->first_child==0) {
      if(tmp->next_sibling==0) {
        // try to walk up and then right again
        do {
          if(tmp==ret.top_node)
             throw std::range_error("tree: begin_fixed out of range");
          tmp=tmp->parent;
               if(tmp==0) 
             throw std::range_error("tree: begin_fixed out of range");
               --curdepth;
           } while(tmp->next_sibling==0);
        }
      tmp=tmp->next_sibling;
      }
    tmp=tmp->first_child;
    ++curdepth;
    }

  ret.node=tmp;
  return ret;
  }

template <class T, class tree_node_allocator>
typename tree<T, tree_node_allocator>::fixed_depth_iterator tree<T, tree_node_allocator>::end_fixed(const iterator_base& pos, unsigned int dp) const
  {
  assert(1==0); // FIXME: not correct yet: use is_valid() as a temporary workaround 
  tree_node *tmp=pos.node;
  unsigned int curdepth=1;
  while(curdepth<dp) { // go down one level
    while(tmp->first_child==0) {
      tmp=tmp->next_sibling;
      if(tmp==0)
        throw std::range_error("tree: end_fixed out of range");
      }
    tmp=tmp->first_child;
    ++curdepth;
    }
  return tmp;
  }

template <class T, class tree_node_allocator>
typename tree<T, tree_node_allocator>::sibling_iterator tree<T, tree_node_allocator>::begin(const iterator_base& pos) const
  {
  assert(pos.node!=0);
  if(pos.node->first_child==0) {
    return end(pos);
    }
  return pos.node->first_child;
  }

template <class T, class tree_node_allocator>
typename tree<T, tree_node_allocator>::sibling_iterator tree<T, tree_node_allocator>::end(const iterator_base& pos) const
  {
  sibling_iterator ret(0);
  ret.parent_=pos.node;
  return ret;
  }

template <class T, class tree_node_allocator>
typename tree<T, tree_node_allocator>::leaf_iterator tree<T, tree_node_allocator>::begin_leaf() const
   {
   tree_node *tmp=head->next_sibling;
   if(tmp!=feet) {
      while(tmp->first_child)
         tmp=tmp->first_child;
      }
   return leaf_iterator(tmp);
   }

template <class T, class tree_node_allocator>
typename tree<T, tree_node_allocator>::leaf_iterator tree<T, tree_node_allocator>::end_leaf() const
   {
   return leaf_iterator(feet);
   }

template <class T, class tree_node_allocator>
typename tree<T, tree_node_allocator>::leaf_iterator tree<T, tree_node_allocator>::begin_leaf(const iterator_base& top) const
   {
  tree_node *tmp=top.node;
  while(tmp->first_child)
     tmp=tmp->first_child;
   return leaf_iterator(tmp, top.node);
   }

template <class T, class tree_node_allocator>
typename tree<T, tree_node_allocator>::leaf_iterator tree<T, tree_node_allocator>::end_leaf(const iterator_base& top) const
   {
   return leaf_iterator(top.node, top.node);
   }

template <class T, class tree_node_allocator>
template <typename iter>
iter tree<T, tree_node_allocator>::parent(iter position) 
  {
  assert(position.node!=0);
  return iter(position.node->parent);
  }

template <class T, class tree_node_allocator>
template <typename iter>
iter tree<T, tree_node_allocator>::previous_sibling(iter position) const
  {
  assert(position.node!=0);
  iter ret(position);
  ret.node=position.node->prev_sibling;
  return ret;
  }

template <class T, class tree_node_allocator>
template <typename iter>
iter tree<T, tree_node_allocator>::next_sibling(iter position) const
  {
  assert(position.node!=0);
  iter ret(position);
  ret.node=position.node->next_sibling;
  return ret;
  }

template <class T, class tree_node_allocator>
template <typename iter>
iter tree<T, tree_node_allocator>::next_at_same_depth(iter position) const
  {
  // We make use of a temporary fixed_depth iterator to implement this.

  typename tree<T, tree_node_allocator>::fixed_depth_iterator tmp(position.node);

  ++tmp;
  return iter(tmp);

//  assert(position.node!=0);
//  iter ret(position);
//
//  if(position.node->next_sibling) {
//    ret.node=position.node->next_sibling;
//    }
//  else { 
//    int relative_depth=0;
//     upper:
//    do {
//      ret.node=ret.node->parent;
//      if(ret.node==0) return ret;
//      --relative_depth;
//      } while(ret.node->next_sibling==0);
//     lower:
//    ret.node=ret.node->next_sibling;
//    while(ret.node->first_child==0) {
//      if(ret.node->next_sibling==0)
//        goto upper;
//      ret.node=ret.node->next_sibling;
//      if(ret.node==0) return ret;
//      }
//    while(relative_depth<0 && ret.node->first_child!=0) {
//      ret.node=ret.node->first_child;
//      ++relative_depth;
//      }
//    if(relative_depth<0) {
//      if(ret.node->next_sibling==0) goto upper;
//      else                          goto lower;
//      }
//    }
//  return ret;
  }

template <class T, class tree_node_allocator>
template <typename iter>
iter tree<T, tree_node_allocator>::append_child(iter position)
   {
  assert(position.node!=head);
  assert(position.node!=feet);
  assert(position.node);

  tree_node *tmp=alloc_.allocate(1,0);
  alloc_.construct(tmp, tree_node_<T>());
//  kp::constructor(&tmp->data);
  tmp->first_child=0;
  tmp->last_child=0;

  tmp->parent=position.node;
  if(position.node->last_child!=0) {
    position.node->last_child->next_sibling=tmp;
    }
  else {
    position.node->first_child=tmp;
    }
  tmp->prev_sibling=position.node->last_child;
  position.node->last_child=tmp;
  tmp->next_sibling=0;
  return tmp;
   }

template <class T, class tree_node_allocator>
template <typename iter>
iter tree<T, tree_node_allocator>::prepend_child(iter position)
   {
  assert(position.node!=head);
  assert(position.node!=feet);
  assert(position.node);

  tree_node *tmp=alloc_.allocate(1,0);
  alloc_.construct(tmp, tree_node_<T>());
//  kp::constructor(&tmp->data);
  tmp->first_child=0;
  tmp->last_child=0;

  tmp->parent=position.node;
  if(position.node->first_child!=0) {
    position.node->first_child->prev_sibling=tmp;
    }
  else {
    position.node->last_child=tmp;
    }
  tmp->next_sibling=position.node->first_child;
  position.node->prev_child=tmp;
  tmp->prev_sibling=0;
  return tmp;
   }

template <class T, class tree_node_allocator>
template <class iter>
iter tree<T, tree_node_allocator>::append_child(iter position, const T& x)
  {
  // If your program fails here you probably used 'append_child' to add the top
  // node to an empty tree. From version 1.45 the top element should be added
  // using 'insert'. See the documentation for further information, and sorry about
  // the API change.
  assert(position.node!=head);
  assert(position.node!=feet);
  assert(position.node);

  tree_node* tmp = alloc_.allocate(1,0);
  alloc_.construct(tmp, x);
//  kp::constructor(&tmp->data, x);
  tmp->first_child=0;
  tmp->last_child=0;

  tmp->parent=position.node;
  if(position.node->last_child!=0) {
    position.node->last_child->next_sibling=tmp;
    }
  else {
    position.node->first_child=tmp;
    }
  tmp->prev_sibling=position.node->last_child;
  position.node->last_child=tmp;
  tmp->next_sibling=0;
  return tmp;
  }

template <class T, class tree_node_allocator>
template <class iter>
iter tree<T, tree_node_allocator>::prepend_child(iter position, const T& x)
  {
  assert(position.node!=head);
  assert(position.node!=feet);
  assert(position.node);

  tree_node* tmp = alloc_.allocate(1,0);
  alloc_.construct(tmp, x);
//  kp::constructor(&tmp->data, x);
  tmp->first_child=0;
  tmp->last_child=0;

  tmp->parent=position.node;
  if(position.node->first_child!=0) {
    position.node->first_child->prev_sibling=tmp;
    }
  else {
    position.node->last_child=tmp;
    }
  tmp->next_sibling=position.node->first_child;
  position.node->first_child=tmp;
  tmp->prev_sibling=0;
  return tmp;
  }

template <class T, class tree_node_allocator>
template <class iter>
iter tree<T, tree_node_allocator>::append_child(iter position, iter other)
  {
  assert(position.node!=head);
  assert(position.node!=feet);
  assert(position.node);

  sibling_iterator aargh=append_child(position, value_type());
  return replace(aargh, other);
  }

template <class T, class tree_node_allocator>
template <class iter>
iter tree<T, tree_node_allocator>::prepend_child(iter position, iter other)
  {
  assert(position.node!=head);
  assert(position.node!=feet);
  assert(position.node);

  sibling_iterator aargh=prepend_child(position, value_type());
  return replace(aargh, other);
  }

template <class T, class tree_node_allocator>
template <class iter>
iter tree<T, tree_node_allocator>::append_children(iter position, sibling_iterator from, sibling_iterator to)
  {
  assert(position.node!=head);
  assert(position.node!=feet);
  assert(position.node);

  iter ret=from;

  while(from!=to) {
    insert_subtree(position.end(), from);
    ++from;
    }
  return ret;
  }

template <class T, class tree_node_allocator>
template <class iter>
iter tree<T, tree_node_allocator>::prepend_children(iter position, sibling_iterator from, sibling_iterator to)
  {
  assert(position.node!=head);
  assert(position.node!=feet);
  assert(position.node);

  iter ret=from;

  while(from!=to) {
    insert_subtree(position.begin(), from);
    ++from;
    }
  return ret;
  }

template <class T, class tree_node_allocator>
typename tree<T, tree_node_allocator>::pre_order_iterator tree<T, tree_node_allocator>::set_head(const T& x)
  {
  assert(head->next_sibling==feet);
  return insert(iterator(feet), x);
  }

template <class T, class tree_node_allocator>
template <class iter>
iter tree<T, tree_node_allocator>::insert(iter position, const T& x)
  {
  if(position.node==0) {
    position.node=feet; // Backward compatibility: when calling insert on a null node,
                        // insert before the feet.
    }
  tree_node* tmp = alloc_.allocate(1,0);
  alloc_.construct(tmp, x);
//  kp::constructor(&tmp->data, x);
  tmp->first_child=0;
  tmp->last_child=0;

  tmp->parent=position.node->parent;
  tmp->next_sibling=position.node;
  tmp->prev_sibling=position.node->prev_sibling;
  position.node->prev_sibling=tmp;

  if(tmp->prev_sibling==0) {
    if(tmp->parent) // when inserting nodes at the head, there is no parent
      tmp->parent->first_child=tmp;
    }
  else
    tmp->prev_sibling->next_sibling=tmp;
  return tmp;
  }

template <class T, class tree_node_allocator>
typename tree<T, tree_node_allocator>::sibling_iterator tree<T, tree_node_allocator>::insert(sibling_iterator position, const T& x)
  {
  tree_node* tmp = alloc_.allocate(1,0);
  alloc_.construct(tmp, x);
//  kp::constructor(&tmp->data, x);
  tmp->first_child=0;
  tmp->last_child=0;

  tmp->next_sibling=position.node;
  if(position.node==0) { // iterator points to end of a subtree
    tmp->parent=position.parent_;
    tmp->prev_sibling=position.range_last();
    tmp->parent->last_child=tmp;
    }
  else {
    tmp->parent=position.node->parent;
    tmp->prev_sibling=position.node->prev_sibling;
    position.node->prev_sibling=tmp;
    }

  if(tmp->prev_sibling==0) {
    if(tmp->parent) // when inserting nodes at the head, there is no parent
      tmp->parent->first_child=tmp;
    }
  else
    tmp->prev_sibling->next_sibling=tmp;
  return tmp;
  }

template <class T, class tree_node_allocator>
template <class iter>
iter tree<T, tree_node_allocator>::insert_after(iter position, const T& x)
  {
  tree_node* tmp = alloc_.allocate(1,0);
  alloc_.construct(tmp, x);
//  kp::constructor(&tmp->data, x);
  tmp->first_child=0;
  tmp->last_child=0;

  tmp->parent=position.node->parent;
  tmp->prev_sibling=position.node;
  tmp->next_sibling=position.node->next_sibling;
  position.node->next_sibling=tmp;

  if(tmp->next_sibling==0) {
    if(tmp->parent) // when inserting nodes at the head, there is no parent
      tmp->parent->last_child=tmp;
    }
  else {
    tmp->next_sibling->prev_sibling=tmp;
    }
  return tmp;
  }

template <class T, class tree_node_allocator>
template <class iter>
iter tree<T, tree_node_allocator>::insert_subtree(iter position, const iterator_base& subtree)
  {
  // insert dummy
  iter it=insert(position, value_type());
  // replace dummy with subtree
  return replace(it, subtree);
  }

template <class T, class tree_node_allocator>
template <class iter>
iter tree<T, tree_node_allocator>::insert_subtree_after(iter position, const iterator_base& subtree)
  {
  // insert dummy
  iter it=insert_after(position, value_type());
  // replace dummy with subtree
  return replace(it, subtree);
  }

// template <class T, class tree_node_allocator>
// template <class iter>
// iter tree<T, tree_node_allocator>::insert_subtree(sibling_iterator position, iter subtree)
//   {
//   // insert dummy
//   iter it(insert(position, value_type()));
//   // replace dummy with subtree
//   return replace(it, subtree);
//   }

template <class T, class tree_node_allocator>
template <class iter>
iter tree<T, tree_node_allocator>::replace(iter position, const T& x)
  {
//  kp::destructor(&position.node->data);
//  kp::constructor(&position.node->data, x);
  position.node->data=x;
//  alloc_.destroy(position.node);
//  alloc_.construct(position.node, x);
  return position;
  }

template <class T, class tree_node_allocator>
template <class iter>
iter tree<T, tree_node_allocator>::replace(iter position, const iterator_base& from)
  {
  assert(position.node!=head);
  tree_node *current_from=from.node;
  tree_node *start_from=from.node;
  tree_node *current_to  =position.node;

  // replace the node at position with head of the replacement tree at from
//  std::cout << "warning!" << position.node << std::endl;
  erase_children(position);  
//  std::cout << "no warning!" << std::endl;
  tree_node* tmp = alloc_.allocate(1,0);
  alloc_.construct(tmp, (*from));
//  kp::constructor(&tmp->data, (*from));
  tmp->first_child=0;
  tmp->last_child=0;
  if(current_to->prev_sibling==0) {
    if(current_to->parent!=0)
      current_to->parent->first_child=tmp;
    }
  else {
    current_to->prev_sibling->next_sibling=tmp;
    }
  tmp->prev_sibling=current_to->prev_sibling;
  if(current_to->next_sibling==0) {
    if(current_to->parent!=0)
      current_to->parent->last_child=tmp;
    }
  else {
    current_to->next_sibling->prev_sibling=tmp;
    }
  tmp->next_sibling=current_to->next_sibling;
  tmp->parent=current_to->parent;
//  kp::destructor(&current_to->data);
  alloc_.destroy(current_to);
  alloc_.deallocate(current_to,1);
  current_to=tmp;
  
  // only at this stage can we fix 'last'
  tree_node *last=from.node->next_sibling;

  pre_order_iterator toit=tmp;
  // copy all children
  do {
    assert(current_from!=0);
    if(current_from->first_child != 0) {
      current_from=current_from->first_child;
      toit=append_child(toit, current_from->data);
      }
    else {
      while(current_from->next_sibling==0 && current_from!=start_from) {
        current_from=current_from->parent;
        toit=parent(toit);
        assert(current_from!=0);
        }
      current_from=current_from->next_sibling;
      if(current_from!=last) {
        toit=append_child(parent(toit), current_from->data);
        }
      }
    } while(current_from!=last);

  return current_to;
  }

template <class T, class tree_node_allocator>
typename tree<T, tree_node_allocator>::sibling_iterator tree<T, tree_node_allocator>::replace(
  sibling_iterator orig_begin, 
  sibling_iterator orig_end, 
  sibling_iterator new_begin, 
  sibling_iterator new_end)
  {
  tree_node *orig_first=orig_begin.node;
  tree_node *new_first=new_begin.node;
  tree_node *orig_last=orig_first;
  while((++orig_begin)!=orig_end)
    orig_last=orig_last->next_sibling;
  tree_node *new_last=new_first;
  while((++new_begin)!=new_end)
    new_last=new_last->next_sibling;

  // insert all siblings in new_first..new_last before orig_first
  bool first=true;
  pre_order_iterator ret;
  while(1==1) {
    pre_order_iterator tt=insert_subtree(pre_order_iterator(orig_first), pre_order_iterator(new_first));
    if(first) {
      ret=tt;
      first=false;
      }
    if(new_first==new_last)
      break;
    new_first=new_first->next_sibling;
    }

  // erase old range of siblings
  bool last=false;
  tree_node *next=orig_first;
  while(1==1) {
    if(next==orig_last) 
      last=true;
    next=next->next_sibling;
    erase((pre_order_iterator)orig_first);
    if(last) 
      break;
    orig_first=next;
    }
  return ret;
  }

template <class T, class tree_node_allocator>
template <typename iter>
iter tree<T, tree_node_allocator>::flatten(iter position)
  {
  if(position.node->first_child==0)
    return position;

  tree_node *tmp=position.node->first_child;
  while(tmp) {
    tmp->parent=position.node->parent;
    tmp=tmp->next_sibling;
    } 
  if(position.node->next_sibling) {
    position.node->last_child->next_sibling=position.node->next_sibling;
    position.node->next_sibling->prev_sibling=position.node->last_child;
    }
  else {
    position.node->parent->last_child=position.node->last_child;
    }
  position.node->next_sibling=position.node->first_child;
  position.node->next_sibling->prev_sibling=position.node;
  position.node->first_child=0;
  position.node->last_child=0;

  return position;
  }


template <class T, class tree_node_allocator>
template <typename iter>
iter tree<T, tree_node_allocator>::reparent(iter position, sibling_iterator begin, sibling_iterator end)
  {
  tree_node *first=begin.node;
  tree_node *last=first;

  assert(first!=position.node);
  
  if(begin==end) return begin;
  // determine last node
  while((++begin)!=end) {
    last=last->next_sibling;
    }
  // move subtree
  if(first->prev_sibling==0) {
    first->parent->first_child=last->next_sibling;
    }
  else {
    first->prev_sibling->next_sibling=last->next_sibling;
    }
  if(last->next_sibling==0) {
    last->parent->last_child=first->prev_sibling;
    }
  else {
    last->next_sibling->prev_sibling=first->prev_sibling;
    }
  if(position.node->first_child==0) {
    position.node->first_child=first;
    position.node->last_child=last;
    first->prev_sibling=0;
    }
  else {
    position.node->last_child->next_sibling=first;
    first->prev_sibling=position.node->last_child;
    position.node->last_child=last;
    }
  last->next_sibling=0;

  tree_node *pos=first;
   for(;;) {
    pos->parent=position.node;
    if(pos==last) break;
    pos=pos->next_sibling;
    }

  return first;
  }

template <class T, class tree_node_allocator>
template <typename iter> iter tree<T, tree_node_allocator>::reparent(iter position, iter from)
  {
  if(from.node->first_child==0) return position;
  return reparent(position, from.node->first_child, end(from));
  }

template <class T, class tree_node_allocator>
template <typename iter> iter tree<T, tree_node_allocator>::wrap(iter position, const T& x)
  {
  assert(position.node!=0);
  sibling_iterator fr=position, to=position;
  ++to;
  iter ret = insert(position, x);
  reparent(ret, fr, to);
  return ret;
  }

template <class T, class tree_node_allocator>
template <typename iter> iter tree<T, tree_node_allocator>::move_after(iter target, iter source)
   {
   tree_node *dst=target.node;
   tree_node *src=source.node;
   assert(dst);
   assert(src);

   if(dst==src) return source;
  if(dst->next_sibling)
    if(dst->next_sibling==src) // already in the right spot
      return source;

   // take src out of the tree
   if(src->prev_sibling!=0) src->prev_sibling->next_sibling=src->next_sibling;
   else                     src->parent->first_child=src->next_sibling;
   if(src->next_sibling!=0) src->next_sibling->prev_sibling=src->prev_sibling;
   else                     src->parent->last_child=src->prev_sibling;

   // connect it to the new point
   if(dst->next_sibling!=0) dst->next_sibling->prev_sibling=src;
   else                     dst->parent->last_child=src;
   src->next_sibling=dst->next_sibling;
   dst->next_sibling=src;
   src->prev_sibling=dst;
   src->parent=dst->parent;
   return src;
   }

template <class T, class tree_node_allocator>
template <typename iter> iter tree<T, tree_node_allocator>::move_before(iter target, iter source)
   {
   tree_node *dst=target.node;
   tree_node *src=source.node;
   assert(dst);
   assert(src);

   if(dst==src) return source;
  if(dst->prev_sibling)
    if(dst->prev_sibling==src) // already in the right spot
      return source;

   // take src out of the tree
   if(src->prev_sibling!=0) src->prev_sibling->next_sibling=src->next_sibling;
   else                     src->parent->first_child=src->next_sibling;
   if(src->next_sibling!=0) src->next_sibling->prev_sibling=src->prev_sibling;
   else                     src->parent->last_child=src->prev_sibling;

   // connect it to the new point
   if(dst->prev_sibling!=0) dst->prev_sibling->next_sibling=src;
   else                     dst->parent->first_child=src;
   src->prev_sibling=dst->prev_sibling;
   dst->prev_sibling=src;
   src->next_sibling=dst;
   src->parent=dst->parent;
   return src;
   }

// specialisation for sibling_iterators
template <class T, class tree_node_allocator>
typename tree<T, tree_node_allocator>::sibling_iterator tree<T, tree_node_allocator>::move_before(sibling_iterator target, 
                                                            sibling_iterator source)
  {
  tree_node *dst=target.node;
  tree_node *src=source.node;
  tree_node *dst_prev_sibling;
  if(dst==0) { // must then be an end iterator
    dst_prev_sibling=target.parent_->last_child;
    assert(dst_prev_sibling);
    }
  else dst_prev_sibling=dst->prev_sibling;
  assert(src);

  if(dst==src) return source;
  if(dst_prev_sibling)
    if(dst_prev_sibling==src) // already in the right spot
      return source;

  // take src out of the tree
  if(src->prev_sibling!=0) src->prev_sibling->next_sibling=src->next_sibling;
  else                     src->parent->first_child=src->next_sibling;
  if(src->next_sibling!=0) src->next_sibling->prev_sibling=src->prev_sibling;
  else                     src->parent->last_child=src->prev_sibling;

  // connect it to the new point
  if(dst_prev_sibling!=0) dst_prev_sibling->next_sibling=src;
  else                    target.parent_->first_child=src;
  src->prev_sibling=dst_prev_sibling;
  if(dst) {
    dst->prev_sibling=src;
    src->parent=dst->parent;
    }
  src->next_sibling=dst;
  return src;
  }

template <class T, class tree_node_allocator>
template <typename iter> iter tree<T, tree_node_allocator>::move_ontop(iter target, iter source)
  {
  tree_node *dst=target.node;
  tree_node *src=source.node;
  assert(dst);
  assert(src);

  if(dst==src) return source;

//  if(dst==src->prev_sibling) {
//
//    }

  // remember connection points
  tree_node *b_prev_sibling=dst->prev_sibling;
  tree_node *b_next_sibling=dst->next_sibling;
  tree_node *b_parent=dst->parent;

  // remove target
  erase(target);

  // take src out of the tree
  if(src->prev_sibling!=0) src->prev_sibling->next_sibling=src->next_sibling;
  else                     src->parent->first_child=src->next_sibling;
  if(src->next_sibling!=0) src->next_sibling->prev_sibling=src->prev_sibling;
  else                     src->parent->last_child=src->prev_sibling;

  // connect it to the new point
  if(b_prev_sibling!=0) b_prev_sibling->next_sibling=src;
  else                  b_parent->first_child=src;
  if(b_next_sibling!=0) b_next_sibling->prev_sibling=src;
  else                  b_parent->last_child=src;
  src->prev_sibling=b_prev_sibling;
  src->next_sibling=b_next_sibling;
  src->parent=b_parent;
  return src;
  }

template <class T, class tree_node_allocator>
void tree<T, tree_node_allocator>::merge(sibling_iterator to1,   sibling_iterator to2,
                            sibling_iterator from1, sibling_iterator from2,
                            bool duplicate_leaves)
  {
  sibling_iterator fnd;
  while(from1!=from2) {
    if((fnd=std::find(to1, to2, (*from1))) != to2) { // element found
      if(from1.begin()==from1.end()) { // full depth reached
        if(duplicate_leaves)
          append_child(parent(to1), (*from1));
        }
      else { // descend further
        merge(fnd.begin(), fnd.end(), from1.begin(), from1.end(), duplicate_leaves);
        }
      }
    else { // element missing
      insert_subtree(to2, from1);
      }
    ++from1;
    }
  }


template <class T, class tree_node_allocator>
void tree<T, tree_node_allocator>::sort(sibling_iterator from, sibling_iterator to, bool deep)
  {
  std::less<T> comp;
  sort(from, to, comp, deep);
  }

template <class T, class tree_node_allocator>
template <class StrictWeakOrdering>
void tree<T, tree_node_allocator>::sort(sibling_iterator from, sibling_iterator to, 
                           StrictWeakOrdering comp, bool deep)
  {
  if(from==to) return;
  // make list of sorted nodes
  // CHECK: if multiset stores equivalent nodes in the order in which they
  // are inserted, then this routine should be called 'stable_sort'.
  std::multiset<tree_node *, compare_nodes<StrictWeakOrdering> > nodes(comp);
  sibling_iterator it=from, it2=to;
  while(it != to) {
    nodes.insert(it.node);
    ++it;
    }
  // reassemble
  --it2;

  // prev and next are the nodes before and after the sorted range
  tree_node *prev=from.node->prev_sibling;
  tree_node *next=it2.node->next_sibling;
  typename std::multiset<tree_node *, compare_nodes<StrictWeakOrdering> >::iterator nit=nodes.begin(), eit=nodes.end();
  if(prev==0) {
    if((*nit)->parent!=0) // to catch "sorting the head" situations, when there is no parent
      (*nit)->parent->first_child=(*nit);
    }
  else prev->next_sibling=(*nit);

  --eit;
  while(nit!=eit) {
    (*nit)->prev_sibling=prev;
    if(prev)
      prev->next_sibling=(*nit);
    prev=(*nit);
    ++nit;
    }
  // prev now points to the last-but-one node in the sorted range
  if(prev)
    prev->next_sibling=(*eit);

  // eit points to the last node in the sorted range.
  (*eit)->next_sibling=next;
   (*eit)->prev_sibling=prev; // missed in the loop above
  if(next==0) {
    if((*eit)->parent!=0) // to catch "sorting the head" situations, when there is no parent
      (*eit)->parent->last_child=(*eit);
    }
  else next->prev_sibling=(*eit);

  if(deep) {  // sort the children of each node too
    sibling_iterator bcs(*nodes.begin());
    sibling_iterator ecs(*eit);
    ++ecs;
    while(bcs!=ecs) {
      sort(begin(bcs), end(bcs), comp, deep);
      ++bcs;
      }
    }
  }

template <class T, class tree_node_allocator>
template <typename iter>
bool tree<T, tree_node_allocator>::equal(const iter& one_, const iter& two, const iter& three_) const
  {
  std::equal_to<T> comp;
  return equal(one_, two, three_, comp);
  }

template <class T, class tree_node_allocator>
template <typename iter>
bool tree<T, tree_node_allocator>::equal_subtree(const iter& one_, const iter& two_) const
  {
  std::equal_to<T> comp;
  return equal_subtree(one_, two_, comp);
  }

template <class T, class tree_node_allocator>
template <typename iter, class BinaryPredicate>
bool tree<T, tree_node_allocator>::equal(const iter& one_, const iter& two, const iter& three_, BinaryPredicate fun) const
  {
  pre_order_iterator one(one_), three(three_);

//  if(one==two && is_valid(three) && three.number_of_children()!=0)
//    return false;
  while(one!=two && is_valid(three)) {
    if(!fun(*one,*three))
      return false;
    if(one.number_of_children()!=three.number_of_children()) 
      return false;
    ++one;
    ++three;
    }
  return true;
  }

template <class T, class tree_node_allocator>
template <typename iter, class BinaryPredicate>
bool tree<T, tree_node_allocator>::equal_subtree(const iter& one_, const iter& two_, BinaryPredicate fun) const
  {
  pre_order_iterator one(one_), two(two_);

  if(!fun(*one,*two)) return false;
  if(number_of_children(one)!=number_of_children(two)) return false;
  return equal(begin(one),end(one),begin(two),fun);
  }

template <class T, class tree_node_allocator>
tree<T, tree_node_allocator> tree<T, tree_node_allocator>::subtree(sibling_iterator from, sibling_iterator to) const
  {
  tree tmp;
  tmp.set_head(value_type());
  tmp.replace(tmp.begin(), tmp.end(), from, to);
  return tmp;
  }

template <class T, class tree_node_allocator>
void tree<T, tree_node_allocator>::subtree(tree& tmp, sibling_iterator from, sibling_iterator to) const
  {
  tmp.set_head(value_type());
  tmp.replace(tmp.begin(), tmp.end(), from, to);
  }

template <class T, class tree_node_allocator>
size_t tree<T, tree_node_allocator>::size() const
  {
  size_t i=0;
  pre_order_iterator it=begin(), eit=end();
  while(it!=eit) {
    ++i;
    ++it;
    }
  return i;
  }

template <class T, class tree_node_allocator>
size_t tree<T, tree_node_allocator>::size(const iterator_base& top) const
  {
  size_t i=0;
  pre_order_iterator it=top, eit=top;
  eit.skip_children();
  ++eit;
  while(it!=eit) {
    ++i;
    ++it;
    }
  return i;
  }

template <class T, class tree_node_allocator>
bool tree<T, tree_node_allocator>::empty() const
  {
  pre_order_iterator it=begin(), eit=end();
  return (it==eit);
  }

template <class T, class tree_node_allocator>
int tree<T, tree_node_allocator>::depth(const iterator_base& it) 
  {
  tree_node* pos=it.node;
  assert(pos!=0);
  int ret=0;
  while(pos->parent!=0) {
    pos=pos->parent;
    ++ret;
    }
  return ret;
  }

template <class T, class tree_node_allocator>
int tree<T, tree_node_allocator>::depth(const iterator_base& it, const iterator_base& root) 
  {
  tree_node* pos=it.node;
  assert(pos!=0);
  int ret=0;
  while(pos->parent!=0 && pos!=root.node) {
    pos=pos->parent;
    ++ret;
    }
  return ret;
  }

template <class T, class tree_node_allocator>
int tree<T, tree_node_allocator>::max_depth() const
  {
  int maxd=-1;
  for(tree_node *it = head->next_sibling; it!=feet; it=it->next_sibling)
    maxd=std::max(maxd, max_depth(it));

  return maxd;
  }


template <class T, class tree_node_allocator>
int tree<T, tree_node_allocator>::max_depth(const iterator_base& pos) const
  {
  tree_node *tmp=pos.node;

  if(tmp==0 || tmp==head || tmp==feet) return -1;

  int curdepth=0, maxdepth=0;
  while(true) { // try to walk the bottom of the tree
    while(tmp->first_child==0) {
      if(tmp==pos.node) return maxdepth;
      if(tmp->next_sibling==0) {
        // try to walk up and then right again
        do {
          tmp=tmp->parent;
               if(tmp==0) return maxdepth;
               --curdepth;
           } while(tmp->next_sibling==0);
        }
         if(tmp==pos.node) return maxdepth;
      tmp=tmp->next_sibling;
      }
    tmp=tmp->first_child;
    ++curdepth;
    maxdepth=std::max(curdepth, maxdepth);
    } 
  }

template <class T, class tree_node_allocator>
unsigned int tree<T, tree_node_allocator>::number_of_children(const iterator_base& it) 
  {
  tree_node *pos=it.node->first_child;
  if(pos==0) return 0;
  
  unsigned int ret=1;
//    while(pos!=it.node->last_child) {
//      ++ret;
//      pos=pos->next_sibling;
//      }
  while((pos=pos->next_sibling))
    ++ret;
  return ret;
  }

template <class T, class tree_node_allocator>
unsigned int tree<T, tree_node_allocator>::number_of_siblings(const iterator_base& it) const
  {
  tree_node *pos=it.node;
  unsigned int ret=0;
  // count forward
  while(pos->next_sibling && 
      pos->next_sibling!=head &&
      pos->next_sibling!=feet) {
    ++ret;
    pos=pos->next_sibling;
    }
  // count backward
  pos=it.node;
  while(pos->prev_sibling && 
      pos->prev_sibling!=head &&
      pos->prev_sibling!=feet) {
    ++ret;
    pos=pos->prev_sibling;
    }
  
  return ret;
  }

template <class T, class tree_node_allocator>
void tree<T, tree_node_allocator>::swap(sibling_iterator it)
  {
  tree_node *nxt=it.node->next_sibling;
  if(nxt) {
    if(it.node->prev_sibling)
      it.node->prev_sibling->next_sibling=nxt;
    else
      it.node->parent->first_child=nxt;
    nxt->prev_sibling=it.node->prev_sibling;
    tree_node *nxtnxt=nxt->next_sibling;
    if(nxtnxt)
      nxtnxt->prev_sibling=it.node;
    else
      it.node->parent->last_child=it.node;
    nxt->next_sibling=it.node;
    it.node->prev_sibling=nxt;
    it.node->next_sibling=nxtnxt;
    }
  }

template <class T, class tree_node_allocator>
void tree<T, tree_node_allocator>::swap(iterator one, iterator two)
  {
  // if one and two are adjacent siblings, use the sibling swap
  if(one.node->next_sibling==two.node) swap(one);
  else if(two.node->next_sibling==one.node) swap(two);
  else {
    tree_node *nxt1=one.node->next_sibling;
    tree_node *nxt2=two.node->next_sibling;
    tree_node *pre1=one.node->prev_sibling;
    tree_node *pre2=two.node->prev_sibling;
    tree_node *par1=one.node->parent;
    tree_node *par2=two.node->parent;

    // reconnect
    one.node->parent=par2;
    one.node->next_sibling=nxt2;
    if(nxt2) nxt2->prev_sibling=one.node;
    else     par2->last_child=one.node;
    one.node->prev_sibling=pre2;
    if(pre2) pre2->next_sibling=one.node;
    else     par2->first_child=one.node;    

    two.node->parent=par1;
    two.node->next_sibling=nxt1;
    if(nxt1) nxt1->prev_sibling=two.node;
    else     par1->last_child=two.node;
    two.node->prev_sibling=pre1;
    if(pre1) pre1->next_sibling=two.node;
    else     par1->first_child=two.node;
    }
  }

// template <class BinaryPredicate>
// tree<T, tree_node_allocator>::iterator tree<T, tree_node_allocator>::find_subtree(
//   sibling_iterator subfrom, sibling_iterator subto, iterator from, iterator to, 
//   BinaryPredicate fun) const
//   {
//   assert(1==0); // this routine is not finished yet.
//   while(from!=to) {
//     if(fun(*subfrom, *from)) {
//       
//       }
//     }
//   return to;
//   }

template <class T, class tree_node_allocator>
bool tree<T, tree_node_allocator>::is_in_subtree(const iterator_base& it, const iterator_base& begin, 
                                 const iterator_base& end) const
  {
  // FIXME: this should be optimised.
  pre_order_iterator tmp=begin;
  while(tmp!=end) {
    if(tmp==it) return true;
    ++tmp;
    }
  return false;
  }

template <class T, class tree_node_allocator>
bool tree<T, tree_node_allocator>::is_valid(const iterator_base& it) const
  {
  if(it.node==0 || it.node==feet || it.node==head) return false;
  else return true;
  }

template <class T, class tree_node_allocator>
typename tree<T, tree_node_allocator>::iterator tree<T, tree_node_allocator>::lowest_common_ancestor(
  const iterator_base& one, const iterator_base& two) const
  {
  std::set<iterator, iterator_base_less> parents;

  // Walk up from 'one' storing all parents.
  iterator walk=one;
  do {
    walk=parent(walk);
    parents.insert(walk);
    } while( is_valid(parent(walk)) );

  // Walk up from 'two' until we encounter a node in parents.
  walk=two;
  do {
    walk=parent(walk);
    if(parents.find(walk) != parents.end()) break;
    } while( is_valid(parent(walk)) );

  return walk;
  }

template <class T, class tree_node_allocator>
unsigned int tree<T, tree_node_allocator>::index(sibling_iterator it) const
  {
  unsigned int ind=0;
  if(it.node->parent==0) {
    while(it.node->prev_sibling!=head) {
      it.node=it.node->prev_sibling;
      ++ind;
      }
    }
  else {
    while(it.node->prev_sibling!=0) {
      it.node=it.node->prev_sibling;
      ++ind;
      }
    }
  return ind;
  }

template <class T, class tree_node_allocator>
typename tree<T, tree_node_allocator>::sibling_iterator tree<T, tree_node_allocator>::sibling(const iterator_base& it, unsigned int num)
   {
   tree_node *tmp;
   if(it.node->parent==0) {
      tmp=head->next_sibling;
      while(num) {
         tmp = tmp->next_sibling;
         --num;
         }
      }
   else {
      tmp=it.node->parent->first_child;
      while(num) {
         assert(tmp!=0);
         tmp = tmp->next_sibling;
         --num;
         }
      }
   return tmp;
   }
 
template <class T, class tree_node_allocator>
void tree<T, tree_node_allocator>::debug_verify_consistency() const
  {
  iterator it=begin();
  while(it!=end()) {
    if(it.node->parent!=0) {
      if(it.node->prev_sibling==0) 
        assert(it.node->parent->first_child==it.node);
      else 
        assert(it.node->prev_sibling->next_sibling==it.node);
      if(it.node->next_sibling==0) 
        assert(it.node->parent->last_child==it.node);
      else
        assert(it.node->next_sibling->prev_sibling==it.node);
      }
    ++it;
    }
  }

template <class T, class tree_node_allocator>
typename tree<T, tree_node_allocator>::sibling_iterator tree<T, tree_node_allocator>::child(const iterator_base& it, unsigned int num) 
  {
  tree_node *tmp=it.node->first_child;
  while(num--) {
    assert(tmp!=0);
    tmp=tmp->next_sibling;
    }
  return tmp;
  }




// Iterator base

template <class T, class tree_node_allocator>
tree<T, tree_node_allocator>::iterator_base::iterator_base()
  : node(0), skip_current_children_(false)
  {
  }

template <class T, class tree_node_allocator>
tree<T, tree_node_allocator>::iterator_base::iterator_base(tree_node *tn)
  : node(tn), skip_current_children_(false)
  {
  }

template <class T, class tree_node_allocator>
T& tree<T, tree_node_allocator>::iterator_base::operator*() const
  {
  return node->data;
  }

template <class T, class tree_node_allocator>
T* tree<T, tree_node_allocator>::iterator_base::operator->() const
  {
  return &(node->data);
  }

template <class T, class tree_node_allocator>
bool tree<T, tree_node_allocator>::post_order_iterator::operator!=(const post_order_iterator& other) const
  {
  if(other.node!=this->node) return true;
  else return false;
  }

template <class T, class tree_node_allocator>
bool tree<T, tree_node_allocator>::post_order_iterator::operator==(const post_order_iterator& other) const
  {
  if(other.node==this->node) return true;
  else return false;
  }

template <class T, class tree_node_allocator>
bool tree<T, tree_node_allocator>::pre_order_iterator::operator!=(const pre_order_iterator& other) const
  {
  if(other.node!=this->node) return true;
  else return false;
  }

template <class T, class tree_node_allocator>
bool tree<T, tree_node_allocator>::pre_order_iterator::operator==(const pre_order_iterator& other) const
  {
  if(other.node==this->node) return true;
  else return false;
  }

template <class T, class tree_node_allocator>
bool tree<T, tree_node_allocator>::sibling_iterator::operator!=(const sibling_iterator& other) const
  {
  if(other.node!=this->node) return true;
  else return false;
  }

template <class T, class tree_node_allocator>
bool tree<T, tree_node_allocator>::sibling_iterator::operator==(const sibling_iterator& other) const
  {
  if(other.node==this->node) return true;
  else return false;
  }

template <class T, class tree_node_allocator>
bool tree<T, tree_node_allocator>::leaf_iterator::operator!=(const leaf_iterator& other) const
   {
   if(other.node!=this->node) return true;
   else return false;
   }

template <class T, class tree_node_allocator>
bool tree<T, tree_node_allocator>::leaf_iterator::operator==(const leaf_iterator& other) const
   {
   if(other.node==this->node && other.top_node==this->top_node) return true;
   else return false;
   }

template <class T, class tree_node_allocator>
typename tree<T, tree_node_allocator>::sibling_iterator tree<T, tree_node_allocator>::iterator_base::begin() const
  {
  if(node->first_child==0) 
    return end();

  sibling_iterator ret(node->first_child);
  ret.parent_=this->node;
  return ret;
  }

template <class T, class tree_node_allocator>
typename tree<T, tree_node_allocator>::sibling_iterator tree<T, tree_node_allocator>::iterator_base::end() const
  {
  sibling_iterator ret(0);
  ret.parent_=node;
  return ret;
  }

template <class T, class tree_node_allocator>
void tree<T, tree_node_allocator>::iterator_base::skip_children()
  {
  skip_current_children_=true;
  }

template <class T, class tree_node_allocator>
void tree<T, tree_node_allocator>::iterator_base::skip_children(bool skip)
   {
   skip_current_children_=skip;
   }

template <class T, class tree_node_allocator>
unsigned int tree<T, tree_node_allocator>::iterator_base::number_of_children() const
  {
  tree_node *pos=node->first_child;
  if(pos==0) return 0;
  
  unsigned int ret=1;
  while(pos!=node->last_child) {
    ++ret;
    pos=pos->next_sibling;
    }
  return ret;
  }



// Pre-order iterator

template <class T, class tree_node_allocator>
tree<T, tree_node_allocator>::pre_order_iterator::pre_order_iterator() 
  : iterator_base(0)
  {
  }

template <class T, class tree_node_allocator>
tree<T, tree_node_allocator>::pre_order_iterator::pre_order_iterator(tree_node *tn)
  : iterator_base(tn)
  {
  }

template <class T, class tree_node_allocator>
tree<T, tree_node_allocator>::pre_order_iterator::pre_order_iterator(const iterator_base &other)
  : iterator_base(other.node)
  {
  }

template <class T, class tree_node_allocator>
tree<T, tree_node_allocator>::pre_order_iterator::pre_order_iterator(const sibling_iterator& other)
  : iterator_base(other.node)
  {
  if(this->node==0) {
    if(other.range_last()!=0)
      this->node=other.range_last();
    else 
      this->node=other.parent_;
    this->skip_children();
    ++(*this);
    }
  }

template <class T, class tree_node_allocator>
typename tree<T, tree_node_allocator>::pre_order_iterator& tree<T, tree_node_allocator>::pre_order_iterator::operator++()
  {
  assert(this->node!=0);
  if(!this->skip_current_children_ && this->node->first_child != 0) {
    this->node=this->node->first_child;
    }
  else {
    this->skip_current_children_=false;
    while(this->node->next_sibling==0) {
      this->node=this->node->parent;
      if(this->node==0)
        return *this;
      }
    this->node=this->node->next_sibling;
    }
  return *this;
  }

template <class T, class tree_node_allocator>
typename tree<T, tree_node_allocator>::pre_order_iterator& tree<T, tree_node_allocator>::pre_order_iterator::operator--()
  {
  assert(this->node!=0);
  if(this->node->prev_sibling) {
    this->node=this->node->prev_sibling;
    while(this->node->last_child)
      this->node=this->node->last_child;
    }
  else {
    this->node=this->node->parent;
    if(this->node==0)
      return *this;
    }
  return *this;
}

template <class T, class tree_node_allocator>
typename tree<T, tree_node_allocator>::pre_order_iterator tree<T, tree_node_allocator>::pre_order_iterator::operator++(int)
  {
  pre_order_iterator copy = *this;
  ++(*this);
  return copy;
  }

template <class T, class tree_node_allocator>
typename tree<T, tree_node_allocator>::pre_order_iterator tree<T, tree_node_allocator>::pre_order_iterator::operator--(int)
{
  pre_order_iterator copy = *this;
  --(*this);
  return copy;
}

template <class T, class tree_node_allocator>
typename tree<T, tree_node_allocator>::pre_order_iterator& tree<T, tree_node_allocator>::pre_order_iterator::operator+=(unsigned int num)
  {
  while(num>0) {
    ++(*this);
    --num;
    }
  return (*this);
  }

template <class T, class tree_node_allocator>
typename tree<T, tree_node_allocator>::pre_order_iterator& tree<T, tree_node_allocator>::pre_order_iterator::operator-=(unsigned int num)
  {
  while(num>0) {
    --(*this);
    --num;
    }
  return (*this);
  }



// Post-order iterator

template <class T, class tree_node_allocator>
tree<T, tree_node_allocator>::post_order_iterator::post_order_iterator() 
  : iterator_base(0)
  {
  }

template <class T, class tree_node_allocator>
tree<T, tree_node_allocator>::post_order_iterator::post_order_iterator(tree_node *tn)
  : iterator_base(tn)
  {
  }

template <class T, class tree_node_allocator>
tree<T, tree_node_allocator>::post_order_iterator::post_order_iterator(const iterator_base &other)
  : iterator_base(other.node)
  {
  }

template <class T, class tree_node_allocator>
tree<T, tree_node_allocator>::post_order_iterator::post_order_iterator(const sibling_iterator& other)
  : iterator_base(other.node)
  {
  if(this->node==0) {
    if(other.range_last()!=0)
      this->node=other.range_last();
    else 
      this->node=other.parent_;
    this->skip_children();
    ++(*this);
    }
  }

template <class T, class tree_node_allocator>
typename tree<T, tree_node_allocator>::post_order_iterator& tree<T, tree_node_allocator>::post_order_iterator::operator++()
  {
  assert(this->node!=0);
  if(this->node->next_sibling==0) {
    this->node=this->node->parent;
    this->skip_current_children_=false;
    }
  else {
    this->node=this->node->next_sibling;
    if(this->skip_current_children_) {
      this->skip_current_children_=false;
      }
    else {
      while(this->node->first_child)
        this->node=this->node->first_child;
      }
    }
  return *this;
  }

template <class T, class tree_node_allocator>
typename tree<T, tree_node_allocator>::post_order_iterator& tree<T, tree_node_allocator>::post_order_iterator::operator--()
  {
  assert(this->node!=0);
  if(this->skip_current_children_ || this->node->last_child==0) {
    this->skip_current_children_=false;
    while(this->node->prev_sibling==0)
      this->node=this->node->parent;
    this->node=this->node->prev_sibling;
    }
  else {
    this->node=this->node->last_child;
    }
  return *this;
  }

template <class T, class tree_node_allocator>
typename tree<T, tree_node_allocator>::post_order_iterator tree<T, tree_node_allocator>::post_order_iterator::operator++(int)
  {
  post_order_iterator copy = *this;
  ++(*this);
  return copy;
  }

template <class T, class tree_node_allocator>
typename tree<T, tree_node_allocator>::post_order_iterator tree<T, tree_node_allocator>::post_order_iterator::operator--(int)
  {
  post_order_iterator copy = *this;
  --(*this);
  return copy;
  }


template <class T, class tree_node_allocator>
typename tree<T, tree_node_allocator>::post_order_iterator& tree<T, tree_node_allocator>::post_order_iterator::operator+=(unsigned int num)
  {
  while(num>0) {
    ++(*this);
    --num;
    }
  return (*this);
  }

template <class T, class tree_node_allocator>
typename tree<T, tree_node_allocator>::post_order_iterator& tree<T, tree_node_allocator>::post_order_iterator::operator-=(unsigned int num)
  {
  while(num>0) {
    --(*this);
    --num;
    }
  return (*this);
  }

template <class T, class tree_node_allocator>
void tree<T, tree_node_allocator>::post_order_iterator::descend_all()
  {
  assert(this->node!=0);
  while(this->node->first_child)
    this->node=this->node->first_child;
  }


// Breadth-first iterator

template <class T, class tree_node_allocator>
tree<T, tree_node_allocator>::breadth_first_queued_iterator::breadth_first_queued_iterator()
  : iterator_base()
  {
  }

template <class T, class tree_node_allocator>
tree<T, tree_node_allocator>::breadth_first_queued_iterator::breadth_first_queued_iterator(tree_node *tn)
  : iterator_base(tn)
  {
  traversal_queue.push(tn);
  }

template <class T, class tree_node_allocator>
tree<T, tree_node_allocator>::breadth_first_queued_iterator::breadth_first_queued_iterator(const iterator_base& other)
  : iterator_base(other.node)
  {
  traversal_queue.push(other.node);
  }

template <class T, class tree_node_allocator>
bool tree<T, tree_node_allocator>::breadth_first_queued_iterator::operator!=(const breadth_first_queued_iterator& other) const
  {
  if(other.node!=this->node) return true;
  else return false;
  }

template <class T, class tree_node_allocator>
bool tree<T, tree_node_allocator>::breadth_first_queued_iterator::operator==(const breadth_first_queued_iterator& other) const
  {
  if(other.node==this->node) return true;
  else return false;
  }

template <class T, class tree_node_allocator>
typename tree<T, tree_node_allocator>::breadth_first_queued_iterator& tree<T, tree_node_allocator>::breadth_first_queued_iterator::operator++()
  {
  assert(this->node!=0);

  // Add child nodes and pop current node
  sibling_iterator sib=this->begin();
  while(sib!=this->end()) {
    traversal_queue.push(sib.node);
    ++sib;
    }
  traversal_queue.pop();
  if(traversal_queue.size()>0)
    this->node=traversal_queue.front();
  else 
    this->node=0;
  return (*this);
  }

template <class T, class tree_node_allocator>
typename tree<T, tree_node_allocator>::breadth_first_queued_iterator tree<T, tree_node_allocator>::breadth_first_queued_iterator::operator++(int)
  {
  breadth_first_queued_iterator copy = *this;
  ++(*this);
  return copy;
  }

template <class T, class tree_node_allocator>
typename tree<T, tree_node_allocator>::breadth_first_queued_iterator& tree<T, tree_node_allocator>::breadth_first_queued_iterator::operator+=(unsigned int num)
  {
  while(num>0) {
    ++(*this);
    --num;
    }
  return (*this);
  }



// Fixed depth iterator

template <class T, class tree_node_allocator>
tree<T, tree_node_allocator>::fixed_depth_iterator::fixed_depth_iterator()
  : iterator_base()
  {
  }

template <class T, class tree_node_allocator>
tree<T, tree_node_allocator>::fixed_depth_iterator::fixed_depth_iterator(tree_node *tn)
  : iterator_base(tn), top_node(0)
  {
  }

template <class T, class tree_node_allocator>
tree<T, tree_node_allocator>::fixed_depth_iterator::fixed_depth_iterator(const iterator_base& other)
  : iterator_base(other.node), top_node(0)
  {
  }

template <class T, class tree_node_allocator>
tree<T, tree_node_allocator>::fixed_depth_iterator::fixed_depth_iterator(const sibling_iterator& other)
  : iterator_base(other.node), top_node(0)
  {
  }

template <class T, class tree_node_allocator>
tree<T, tree_node_allocator>::fixed_depth_iterator::fixed_depth_iterator(const fixed_depth_iterator& other)
  : iterator_base(other.node), top_node(other.top_node)
  {
  }

template <class T, class tree_node_allocator>
bool tree<T, tree_node_allocator>::fixed_depth_iterator::operator==(const fixed_depth_iterator& other) const
  {
  if(other.node==this->node && other.top_node==top_node) return true;
  else return false;
  }

template <class T, class tree_node_allocator>
bool tree<T, tree_node_allocator>::fixed_depth_iterator::operator!=(const fixed_depth_iterator& other) const
  {
  if(other.node!=this->node || other.top_node!=top_node) return true;
  else return false;
  }

template <class T, class tree_node_allocator>
typename tree<T, tree_node_allocator>::fixed_depth_iterator& tree<T, tree_node_allocator>::fixed_depth_iterator::operator++()
  {
  assert(this->node!=0);

  if(this->node->next_sibling) {
    this->node=this->node->next_sibling;
    }
  else { 
    int relative_depth=0;
     upper:
    do {
      if(this->node==this->top_node) {
        this->node=0; // FIXME: return a proper fixed_depth end iterator once implemented
        return *this;
        }
      this->node=this->node->parent;
      if(this->node==0) return *this;
      --relative_depth;
      } while(this->node->next_sibling==0);
     lower:
    this->node=this->node->next_sibling;
    while(this->node->first_child==0) {
      if(this->node->next_sibling==0)
        goto upper;
      this->node=this->node->next_sibling;
      if(this->node==0) return *this;
      }
    while(relative_depth<0 && this->node->first_child!=0) {
      this->node=this->node->first_child;
      ++relative_depth;
      }
    if(relative_depth<0) {
      if(this->node->next_sibling==0) goto upper;
      else                          goto lower;
      }
    }
  return *this;
  }

template <class T, class tree_node_allocator>
typename tree<T, tree_node_allocator>::fixed_depth_iterator& tree<T, tree_node_allocator>::fixed_depth_iterator::operator--()
  {
  assert(this->node!=0);

  if(this->node->prev_sibling) {
    this->node=this->node->prev_sibling;
    }
  else { 
    int relative_depth=0;
     upper:
    do {
      if(this->node==this->top_node) {
        this->node=0;
        return *this;
        }
      this->node=this->node->parent;
      if(this->node==0) return *this;
      --relative_depth;
      } while(this->node->prev_sibling==0);
     lower:
    this->node=this->node->prev_sibling;
    while(this->node->last_child==0) {
      if(this->node->prev_sibling==0)
        goto upper;
      this->node=this->node->prev_sibling;
      if(this->node==0) return *this;
      }
    while(relative_depth<0 && this->node->last_child!=0) {
      this->node=this->node->last_child;
      ++relative_depth;
      }
    if(relative_depth<0) {
      if(this->node->prev_sibling==0) goto upper;
      else                            goto lower;
      }
    }
  return *this;

//
//
//  assert(this->node!=0);
//  if(this->node->prev_sibling!=0) {
//    this->node=this->node->prev_sibling;
//    assert(this->node!=0);
//    if(this->node->parent==0 && this->node->prev_sibling==0) // head element
//      this->node=0;
//    }
//  else {
//    tree_node *par=this->node->parent;
//    do {
//      par=par->prev_sibling;
//      if(par==0) { // FIXME: need to keep track of this!
//        this->node=0;
//        return *this;
//        }
//      } while(par->last_child==0);
//    this->node=par->last_child;
//    }
//  return *this;
  }

template <class T, class tree_node_allocator>
typename tree<T, tree_node_allocator>::fixed_depth_iterator tree<T, tree_node_allocator>::fixed_depth_iterator::operator++(int)
  {
  fixed_depth_iterator copy = *this;
  ++(*this);
  return copy;
  }

template <class T, class tree_node_allocator>
typename tree<T, tree_node_allocator>::fixed_depth_iterator tree<T, tree_node_allocator>::fixed_depth_iterator::operator--(int)
   {
  fixed_depth_iterator copy = *this;
  --(*this);
  return copy;
  }

template <class T, class tree_node_allocator>
typename tree<T, tree_node_allocator>::fixed_depth_iterator& tree<T, tree_node_allocator>::fixed_depth_iterator::operator-=(unsigned int num)
  {
  while(num>0) {
    --(*this);
    --(num);
    }
  return (*this);
  }

template <class T, class tree_node_allocator>
typename tree<T, tree_node_allocator>::fixed_depth_iterator& tree<T, tree_node_allocator>::fixed_depth_iterator::operator+=(unsigned int num)
  {
  while(num>0) {
    ++(*this);
    --(num);
    }
  return *this;
  }


// Sibling iterator

template <class T, class tree_node_allocator>
tree<T, tree_node_allocator>::sibling_iterator::sibling_iterator() 
  : iterator_base()
  {
  set_parent_();
  }

template <class T, class tree_node_allocator>
tree<T, tree_node_allocator>::sibling_iterator::sibling_iterator(tree_node *tn)
  : iterator_base(tn)
  {
  set_parent_();
  }

template <class T, class tree_node_allocator>
tree<T, tree_node_allocator>::sibling_iterator::sibling_iterator(const iterator_base& other)
  : iterator_base(other.node)
  {
  set_parent_();
  }

template <class T, class tree_node_allocator>
tree<T, tree_node_allocator>::sibling_iterator::sibling_iterator(const sibling_iterator& other)
  : iterator_base(other), parent_(other.parent_)
  {
  }

template <class T, class tree_node_allocator>
void tree<T, tree_node_allocator>::sibling_iterator::set_parent_()
  {
  parent_=0;
  if(this->node==0) return;
  if(this->node->parent!=0)
    parent_=this->node->parent;
  }

template <class T, class tree_node_allocator>
typename tree<T, tree_node_allocator>::sibling_iterator& tree<T, tree_node_allocator>::sibling_iterator::operator++()
  {
  if(this->node)
    this->node=this->node->next_sibling;
  return *this;
  }

template <class T, class tree_node_allocator>
typename tree<T, tree_node_allocator>::sibling_iterator& tree<T, tree_node_allocator>::sibling_iterator::operator--()
  {
  if(this->node) this->node=this->node->prev_sibling;
  else {
    assert(parent_);
    this->node=parent_->last_child;
    }
  return *this;
}

template <class T, class tree_node_allocator>
typename tree<T, tree_node_allocator>::sibling_iterator tree<T, tree_node_allocator>::sibling_iterator::operator++(int)
  {
  sibling_iterator copy = *this;
  ++(*this);
  return copy;
  }

template <class T, class tree_node_allocator>
typename tree<T, tree_node_allocator>::sibling_iterator tree<T, tree_node_allocator>::sibling_iterator::operator--(int)
  {
  sibling_iterator copy = *this;
  --(*this);
  return copy;
  }

template <class T, class tree_node_allocator>
typename tree<T, tree_node_allocator>::sibling_iterator& tree<T, tree_node_allocator>::sibling_iterator::operator+=(unsigned int num)
  {
  while(num>0) {
    ++(*this);
    --num;
    }
  return (*this);
  }

template <class T, class tree_node_allocator>
typename tree<T, tree_node_allocator>::sibling_iterator& tree<T, tree_node_allocator>::sibling_iterator::operator-=(unsigned int num)
  {
  while(num>0) {
    --(*this);
    --num;
    }
  return (*this);
  }

template <class T, class tree_node_allocator>
typename tree<T, tree_node_allocator>::tree_node *tree<T, tree_node_allocator>::sibling_iterator::range_first() const
  {
  tree_node *tmp=parent_->first_child;
  return tmp;
  }

template <class T, class tree_node_allocator>
typename tree<T, tree_node_allocator>::tree_node *tree<T, tree_node_allocator>::sibling_iterator::range_last() const
  {
  return parent_->last_child;
  }

// Leaf iterator

template <class T, class tree_node_allocator>
tree<T, tree_node_allocator>::leaf_iterator::leaf_iterator() 
   : iterator_base(0), top_node(0)
   {
   }

template <class T, class tree_node_allocator>
tree<T, tree_node_allocator>::leaf_iterator::leaf_iterator(tree_node *tn, tree_node *top)
   : iterator_base(tn), top_node(top)
   {
   }

template <class T, class tree_node_allocator>
tree<T, tree_node_allocator>::leaf_iterator::leaf_iterator(const iterator_base &other)
   : iterator_base(other.node), top_node(0)
   {
   }

template <class T, class tree_node_allocator>
tree<T, tree_node_allocator>::leaf_iterator::leaf_iterator(const sibling_iterator& other)
   : iterator_base(other.node), top_node(0)
   {
   if(this->node==0) {
      if(other.range_last()!=0)
         this->node=other.range_last();
      else 
         this->node=other.parent_;
      ++(*this);
      }
   }

template <class T, class tree_node_allocator>
typename tree<T, tree_node_allocator>::leaf_iterator& tree<T, tree_node_allocator>::leaf_iterator::operator++()
   {
  assert(this->node!=0);
  if(this->node->first_child!=0) { // current node is no longer leaf (children got added)
     while(this->node->first_child) 
        this->node=this->node->first_child;
     }
  else {
     while(this->node->next_sibling==0) { 
        if (this->node->parent==0) return *this;
        this->node=this->node->parent;
        if (top_node != 0 && this->node==top_node) return *this;
        }
     this->node=this->node->next_sibling;
     while(this->node->first_child)
        this->node=this->node->first_child;
     }
  return *this;
   }

template <class T, class tree_node_allocator>
typename tree<T, tree_node_allocator>::leaf_iterator& tree<T, tree_node_allocator>::leaf_iterator::operator--()
   {
  assert(this->node!=0);
  while (this->node->prev_sibling==0) {
    if (this->node->parent==0) return *this;
    this->node=this->node->parent;
    if (top_node !=0 && this->node==top_node) return *this; 
    }
  this->node=this->node->prev_sibling;
  while(this->node->last_child)
    this->node=this->node->last_child;
  return *this;
  }

template <class T, class tree_node_allocator>
typename tree<T, tree_node_allocator>::leaf_iterator tree<T, tree_node_allocator>::leaf_iterator::operator++(int)
   {
   leaf_iterator copy = *this;
   ++(*this);
   return copy;
   }

template <class T, class tree_node_allocator>
typename tree<T, tree_node_allocator>::leaf_iterator tree<T, tree_node_allocator>::leaf_iterator::operator--(int)
   {
   leaf_iterator copy = *this;
   --(*this);
   return copy;
   }


template <class T, class tree_node_allocator>
typename tree<T, tree_node_allocator>::leaf_iterator& tree<T, tree_node_allocator>::leaf_iterator::operator+=(unsigned int num)
   {
   while(num>0) {
      ++(*this);
      --num;
      }
   return (*this);
   }

template <class T, class tree_node_allocator>
typename tree<T, tree_node_allocator>::leaf_iterator& tree<T, tree_node_allocator>::leaf_iterator::operator-=(unsigned int num)
   {
   while(num>0) {
      --(*this);
      --num;
      }
   return (*this);
   }

}  // namespace internal

using internal::tree;

}  // namespace gmml

#endif  // GMML_INTERNAL_TREE_H_
